
#include "../../engine.h"

#include "../../User.h"

#include "../../NLogic/Space.h"
#include "../../NLogic/Battle.h"

#include "matching.h"

namespace ProjectZ { namespace NCommand { namespace NMatching {

/*
 * 던전 맵 완료 후 다른 맵으로 이동 시 가능 여부 확인 패킷
 * auth : jjaehuny@gamevil.com
 */

void CS_DUNGEON_ENABLE_MAP_CHANGE::OnExecute(User * pUser, ::Network::Packet * pPacket)
{
	/* message
	 * CS_DUNGEON_ENABLE_MAP_CHANGE	0x0808		4	unsigned int	GID : 게임 유니크 Key
		2	unsigned short	맵 TID
		2	unsigned short	전환 후X좌표
		2	unsigned short	전환 후Y좌표
		2	unsigned short	"방향 벡터(보고있는 방향 0 : RIGHT, 90 : DOWN..)"
		1	char	맵전환 가능 여부알림 ( 0: 불가능 1: 가능)
	 */

	//
	NLogic::Space * pSpace = pUser->GetSpace();
	if (NULL == pSpace)
	{
		DEBUGLOG("CS_DUNGEON_ENABLE_MAP_CHANGE NULL == pSpace");
		return;
	}

	if (false == pSpace->IsDungeon())
	{
		DEBUGLOG("CS_DUNGEON_ENABLE_MAP_CHANGE space is not single or party dungeion");
		return;
	}


	PREPARE_PACKET;

	int gid = 0;
	uint16_t map_tid = 0;
	int x = 0;
	int y = 0;
	int degree = 0;
	char enable = 0;

	pPacket->ParseMsg("%d%2d%2d%2d%2d%c", &gid, &map_tid, &x, &y, &degree, &enable);

	DEBUGLOG("GID %d CS_DUNGEON_ENABLE_MAP_CHANGE, map_tid=%d, degree=%d, enable=%d", pUser->GetUserSeq(), map_tid, degree, enable);

	const NLogic::Space::USERTREE & clsUserTree = pSpace->GetUserTree();
	if (true == clsUserTree.empty())
		return;

	// 맵 전환이 가능한 상태로 들어온 경우...
	if (enable == 1 && false == pUser->GetBattle()->GetData()._enable_map_clear)
	{
		if (0 < pSpace->GetMonsterCount())
			return;

		pUser->GetBattle()->GetData().x = x;
		pUser->GetBattle()->GetData().y = y;
		pUser->GetBattle()->GetData().degree = degree;

		bool able = true;
		pSpace->GetData()._enableCount ++;
		pUser->GetBattle()->GetData()._enable_map_clear = true;
		pSpace->GetData()._degree = degree;

		// 전체 유저가 모두 들어온 경우...
		if ( (int)clsUserTree.size() == pSpace->GetData()._enableCount)
		{
			NLogic::Space::USERTREE::const_iterator citr = clsUserTree.begin();
			for(;citr != clsUserTree.end(); citr++)
			{
				User * pTargetUser = ( * citr ).second;

				if (pTargetUser->GetBattle()->GetData()._enable_map_clear == 0)// || pUser->player_info.degree != pTargetUser->player_info.degree )
				{
					able = false;
					break;
				}
			}

			if( able == true )
			{
				// 모두 가능 상태이므로 이때 맵 아이디를 변경해야 한다.
				NLogic::Space::USERTREE::const_iterator citr = clsUserTree.begin();
				for(;citr != clsUserTree.end(); citr++)
				{
					User * pTargetUser = ( * citr ).second;
					pTargetUser->GetBattle()->GetData()._enable_map_clear = false;
					pSpace->ClearMonsterTree();
				}

				pSpace->GetData()._mapTid = map_tid;

				DEBUGLOG("CS_DUNGEON_ENABLE_MAP_CHANGE SEND MAP TID : %d", pSpace->GetData()._mapTid);

				::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
//				pNoti->MsgCat("%2d%2d%2d%2d", pSpace->GetData()._mapTid, pUser->player_info.x, pUser->player_info.y, pUser->player_info.degree);
				pNoti->MsgCat("%2d%2d%2d%2d", pSpace->GetData()._mapTid, pUser->GetBattle()->GetData().x, pUser->GetBattle()->GetData().y, pUser->GetBattle()->GetData().degree);
				pNoti->MakePacket(CMD_SN_DUNGEON_MAP_CHANGE);
				pSpace->SendAll(pNoti);

				pSpace->GetData()._enableCount = 0;
				pSpace->ClearMonsterTree();
				pSpace->ClearDeadMonsterTree();
			}

			return;
		}

		// 과반수 이상 이동 할수 있는 지역에 들어온 경우 카운트를 진행 하도록 패킷 전송...
		// 과반수 이하로 남은 경우 정지하도록 패킷 전송
		int mod = (clsUserTree.size() % 2);
		int value = 0;
		if (0 == mod)
		{
			value = clsUserTree.size() / 2;
		}
		else
		{
			value = clsUserTree.size() / 2 + 1;
		}

		if (value <= pSpace->GetData()._enableCount)
		{
			NLogic::Space::USERTREE::const_iterator citr = clsUserTree.begin();
			for(;citr != clsUserTree.end(); citr++)
			{
				::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
				uint8_t count = 5;
				* pAck << count;
				* pAck << map_tid;
				pAck->MakePacket(CMD_SN_DUNGEON_MAP_CHANGE_COUNT);

				User * pTargetUser = ( * citr ).second;
				pTargetUser->Send(pAck);
			}

			//pSpace->GetData()._nextMapTid = map_tid;

			return;
		}

		return;
	}


	pUser->GetBattle()->GetData()._enable_map_clear = false;
	pSpace->GetData()._enableCount--;
	if (0 > pSpace->GetData()._enableCount)
		pSpace->GetData()._enableCount = 0;

	// 과반수 이하로 남은 경우 정지하도록 패킷 전송
	int mod = (clsUserTree.size() % 2);
	int value = 0;
	if (0 == mod)
	{
		value = clsUserTree.size() / 2;
	}
	else
	{
		value = clsUserTree.size() / 2 + 1;
	}

	if (value > pSpace->GetData()._enableCount)
	{
		NLogic::Space::USERTREE::const_iterator citr = clsUserTree.begin();
		for(;citr != clsUserTree.end(); citr++)
		{
			::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
			uint8_t count = 0;
			* pAck << count;
			* pAck << map_tid;
			DEBUGLOG("CMD_SN_DUNGEON_MAP_CHANGE_COUNT 2");
			pAck->MakePacket(CMD_SN_DUNGEON_MAP_CHANGE_COUNT);

			User * pTargetUser = ( * citr ).second;
			pTargetUser->Send(pAck);
		}
		//pSpace->GetData()._nextMapTid = map_tid;
	}
}

} /*NBattle*/ } /*NCommand*/ } /*ProjectZ*/
